import time

import logo.Mlog
from dataTemp.prop import Prop
from match.font import get_plz
from process.Copy import Copy
from process.chooseCharacter import chooseCharacter, chooseCharacter3
from taskPro import taskPro
from tool.test import VectorManager
from tool.vector import Vector


class Fight:
    def __init__(self, cy: Copy):
        self.cy = cy
        self.times: int = 0

    cy: Copy = None

    def enter(self):
        logo.Mlog.logger.error(f"进入战斗状态{self.cy.first_room}")
        # self.cy.cut_room_reset()
        self.final_skill_times = 0
        self.times = 0

    final_skill_times: int = 0

    def run(self):
        # logo.Mlog.logger.debug(f"运行战斗状态 狮子头房间={self.cy.leo_room}，self.times={self.times}")
        if self.times > 100 and not self.cy.leo_room:
            self.times += 1
            if len(self.cy.enemy) > 0:
                logo.Mlog.logger.error(f"运行战斗状态 超时")
                p = min(self.cy.enemy, key=lambda e: Vector.distance(e.getPot(), self.cy.player.position))
                self.cy.player.find_way(p.getPot())
                if self.times > 110:
                    self.times = 0
                return
            else:
                self.cy.player.random_move()
                if self.times > 110:
                    self.times = 0
                return

        self.cy.player.add_buff()
        if self.cy.leo_room:
            self.cy.player.position.y -= self.cy.player.wh.y / 3
            if self.final_skill_times == 0:
                self.cy.player.final_skill()
            elif 80 <= self.final_skill_times <= 82:
                self.cy.player.final_skill()
            else:
                self.cy.player.releaseSkill(self.cy, self.cy.enemy)
        else:
            self.cy.player.releaseSkill(self.cy, self.cy.enemy)
        self.final_skill_times += 1
        self.times += 1

    def exit(self):
        logo.Mlog.logger.debug(f"退出战斗状态")
        self.final_skill_times = 0
        self.times = 0


class PickStuff:
    def __init__(self, cy: Copy):
        self.cy = cy

    cy: Copy = None

    def enter(self):
        logo.Mlog.logger.error(f"进入 捡材料 状态")
        self.times: int = 0

    def run(self):

        # 如果寻路次数过多，可能是卡住了
        self.times += 1
        if self.times > 100:
            self.cy.player.random_move()
            logo.Mlog.logger.warning(f"进入 捡材料 卡住了 自由移动一下")
            self.cy.sm.transition_to("et")
            self.times = 0
            return
        if len(self.cy.stuff) <= 0: return
        # if self.cy.player.temp_pot is None:
        #     return
        # logo.Mlog.logger.debug(f"运行 捡材料 状态 ={self.cy.stuff[0].getPot()}")
        self.cy.player.find_way(self.cy.stuff[0].getPot())

    def exit(self):
        logo.Mlog.logger.debug(f"退出 捡材料 状态")


class FindWay:
    def __init__(self, cy: Copy):
        self.cy = cy
        self.pot = None

    cy: Copy = None
    pots_manager: VectorManager = VectorManager(30)

    def enter(self):
        logo.Mlog.logger.error(f"进入 寻路 状态")
        # self.cy.cut_room_reset()
        # self.cy.move_enemy_pots()
        self.pots_manager.clear()
        self.times = 0

        # self.enemy_pots = list(self.cy.boss_move_pots.values())

    # move_index: int = 0
    times: int = 0

    def run(self):

        self.pots_manager.add_vector(self.cy.player.temp_pot)
        if self.pots_manager.most_frequent_count() >= 10:
            self.cy.player.random_move()
            self.pots_manager.clear()
            logo.Mlog.logger.warning(f"进入 寻路 长时间原地不动 自由移动一下")
            return
        # logo.Mlog.logger.debug(f"运行 寻路 状态 {len(self.cy.guidepost)}")
        # self.cy.check_tank_end_guidepost()
        # 如果寻路次数过多，可能是卡住了
        self.times += 1
        if self.times > 200:
            self.cy.player.random_move()
            self.cy.sm.transition_to("et")
            logo.Mlog.logger.warning(f"进入 寻路 卡住了 自由移动一下")
            self.times = 0
            return

        # 最终房间的路标只要出现一次，后面没有检测到，也不要消失
        filtered_list = [x for x in self.cy.exports if x.name == "领主入口"]
        if len(filtered_list) > 1 and not self.cy.leo_ok:
            v = filtered_list[0].getPot() + filtered_list[1].getPot()
            v.scale(0.5)
            self.cy.player.find_way(v, 0.5)
            return
        # 寻路的时候，遇到终点路标加进去
        if self.cy.end_guidepost:
            if len(self.cy.guidepost) == 0 and not len(self.cy.exports) == 0:
                self.cy.guidepost.append(self.cy.end_guidepost)
            else:
                for egp in self.cy.guidepost:
                    if not self.cy.end_guidepost.name == egp.name:
                        self.cy.guidepost.append(self.cy.end_guidepost)
        if len(self.cy.exports) > 0 and self.cy.end_guidepost:
            filtered_list = [x for x in self.cy.exports if
                             Vector.distance(x.getPot(),
                                             self.cy.end_guidepost.getPot()) <= self.cy.end_guidepost.getWH().y * 3]

            if len(filtered_list) >= 2:
                v = filtered_list[0].getPot() + filtered_list[1].getPot()
                v.scale(0.5)
                self.cy.guidepost.append(Prop("", [v.x, v.y, 0, 0]))
                logo.Mlog.logger.warning(f"进入 寻路 门柱之间的距离{v}")
        # 寻路之前，如果遇到了目标门柱，把目标门柱加入寻路列表
        # 找到x距离最近的
        if len(self.cy.guidepost) <= 0 and self.cy.player.temp_pot is None:
            self.cy.player.random_move()
            logo.Mlog.logger.warning(f"进入 寻路 路标和自己都找不到 自由移动一下")
            return
        # 切换房间后，当路标检测到了，角色可能还没有检测到，使用的角色的坐标还是上一个房间的，不能使用。继续上一个房间的方向移动一小段距离
        # # # 找到x距离最近的
        if self.cy.player.temp_pot is None and len(self.cy.guidepost) > 1:
            # pts=sorted(self.cy.guidepost, key=lambda x: x.pot.length)
            mx = max(self.cy.guidepost, key=lambda e: e.getPot().length)
            mi = min(self.cy.guidepost, key=lambda e: e.getPot().length)
            # self.cy.player.temp_pot = mi.pot
            # self.cy.player.position = mi.pot
            logo.Mlog.logger.warning(f"进入 寻路 找不到自己 ，向朝着路标的方向走一段{mi.getPot()}={mx.getPot()}")
            self.cy.player.yg.move(mi.getPot(), mx.getPot(), 0.3)
            return

        if len(self.cy.guidepost) <= 0 or self.cy.player.get_down_pot() is None: return
        self.pot = max(self.cy.guidepost, key=lambda e: Vector.distance(self.cy.player.get_down_pot(), e.getPot()))

        if self.pot.name == "路标领主" and not self.cy.leo_ok:
            return
        # elif p.name == "路标移动" or p.name == "路标领主":
        #     self.pot = p
        #     break
        if self.pot.name == "路标移动" or self.pot.name == "路标领主":
            self.cy.player.find_way(self.pot.getPot(), 0.3)
        else:
            self.cy.player.find_way(self.pot.getPot(), 0.08)
        # 找到x距离最近的
        if len(self.cy.guidepost) <= 0 < len(self.cy.exports) and not (self.cy.player.temp_pot is None):
            mi = min(self.cy.exports, key=lambda e: Vector.distance(e.getPot(), self.cy.player.temp_pot))
            self.cy.player.find_way(self.cy.player.temp_pot.getPot() - mi.getPot())
            logo.Mlog.logger.warning(f"进入 寻路 路标找不到 移动一下")
            return
        # Mlog.logger.debug(f"寻找路标{self.cy.player.get_down_pot()}= {self.pot.name}={self.pot.pot}")

    def exit(self):
        logo.Mlog.logger.debug(f"退出 寻路 状态")


class Through:
    def __init__(self, cy: Copy):
        self.cy = cy
        self.times = 0
        self.currTimes = 0

    cy: Copy = None
    i: int = 0

    enemy_pots: [Vector] = []
    is_ok: bool = False

    def enter(self):
        self.times = 0
        logo.Mlog.logger.error(f"进入 通关 状态==={self.cy.role.currTimes}")
        # 重置属性
        self.cy.reset_Copy()
        # self.cy.cut_room_reset()
        self.cy.agan_fail_times = 0
        # 判断当前角色是否打满了
        # self.cy.check_pl()
        # if self.cy.role.currTimes >= self.cy.role.totalTimes - 2:
        #     self.cy.check_pl()
        # else:
        if self.cy.role.currTimes == 4 or self.cy.role.currTimes== 9:
            logo.Mlog.logger.error(f"进入 通关 状态  到达中场休息==={self.cy.role.currTimes}")
            action = taskPro.getAction("backTown")
            if action.click():
                self.cy.is_at_town = True
                # 返回城镇成功，进入切换角色状态
                logo.Mlog.logger.debug("返回城镇成功")
                time.sleep(60 * 3)
                ast = taskPro.getAction("goToBuWanJia2")
                goToBuWanJia_ok = ast.click()
                if goToBuWanJia_ok:
                    # 返回城镇成功，进入切换角色状态
                    plz = get_plz()
                    time.sleep(0.5)
                    if plz == 0 or plz is None:
                        action = taskPro.getAction("backTown2")
                        action.click()
                        logo.Mlog.logger.debug(f"进入 布万家 失败 没有疲劳值了 {plz},切换角色")
                        self.cy.sm.transition_to("house")
                        return
                    else:
                        ast = taskPro.getAction("fightBegen")
                        ast.click()
                        self.cy.sm.transition_to("et")
                        self.cy.is_at_town = False
                        logo.Mlog.logger.debug(f"进入 布万家 成功")
                        self.cy.role.currTimes += 1
                        return

        action = taskPro.getAction("challengeAgain")
        if action.click():
            self.cy.role.currTimes += 1
            logo.Mlog.logger.error(f"========再次挑战成功========={self.cy.role.currTimes}")
            # self.cy.sm.transition_to("et")
            return
        else:
            logo.Mlog.logger.debug("再次挑战失败")
            return

    # move_index: int = 0

    def run(self):
        self.times += 1
        if self.times >= 100:
            self.times = 0
            # self.cy.check_pl()
            logo.Mlog.logger.error(f" 点击 再次挑战 超出了次数了")
            self.cy.back_town()


        # logo.Mlog.logger.debug(f"运行 通关 状态")
        # if self.is_ok: return
        for ic in self.cy.ico:
            if ic == "加载过渡":
                self.cy.sm.transition_to("et")
                return
        pass

    def exit(self):
        logo.Mlog.logger.debug(f"退出 通关 状态")
        # self.move_index = 0
        # self.is_ok = False


class leo_pre_room:
    def __init__(self, cy: Copy):
        self.cut_nmb = 0
        self.cy = cy

    cy: Copy = None
    i: int = 0
    player_is_left: bool = False
    player_is_up: bool = False

    def enter(self):
        logo.Mlog.logger.error(f"进入 狮子头前一个房间 状态")
        self.i = 0
        self.player_is_up = False
        self.zst_pro_times = 0
        self.cy.player.yg.mouse_controller.clear_mouse()
        # direction = Vector(-self.cy.player.get_down_pot().x, self.cy.player.get_down_pot().y + 500)
        # self.cy.player.up_move(0.1)
        # self.cy.player.key_pro.clear_key()
        # 先往左跑一秒，确保能识别到左边的门口
        # if self.a1:

    # a1: bool = True
    zst_pro_times: int = 0
    i_pot = set()
    speed: float = 3

    def run(self):
        # logo.Mlog.logger.debug(f"运行 狮子头前一个房间 状态={self.zst_pro_times}")
        # if len(self.cy.guidepost) <= 0: return
        # if self.cy.cut_nmb >= 2:
        #     self.speed = 1
        # else:
        #     self.speed = 3
        self.zst_pro_times += 1
        # 如果式了5次都没有成功，那么大概率不是狮子头的前一个房间了
        if self.zst_pro_times > 350:
            self.cy.leo_pre_room = False
            self.zst_pro_times = 0
            self.cut_nmb = 0
            # self.cy.leo_ok = True
            logo.Mlog.logger.debug(f"进入 狮子头前一个房间 失败")
        if self.cy.player.get_down_pot is None: return
        direction = Vector(-self.cy.player.get_down_pot().x, self.cy.player.get_down_pot().y)
        if len(self.cy.exports) <= 0 or len(self.cy.guidepost) <= 0:
            self.cy.player.find_way(direction, 0.3)
            return
        else:
            p = min(self.cy.exports, key=lambda e: Vector.distance(self.cy.player.get_down_pot(), e.getPot()))
            # p.pot.x > self.cy.player.get_down_pot().x or math.fabs(
            #                     p.pot.y - self.cy.player.position.y) > self.cy.player.wh.y
            if not (self.cy.closest_edge(p.getPot(), self.cy.rect)) == 0:
                v = max(self.cy.guidepost, key=lambda e: Vector.distance(self.cy.player.get_down_pot(), e.getPot()))
                direction = Vector(-v.getPot().x, v.getPot().y)
                self.cy.player.find_way(direction, 0.3)
            else:
                # self.pot = p.pot
                if p.x > self.cy.player.get_down_pot().x:
                    v = max(self.cy.guidepost, key=lambda e: Vector.distance(self.cy.player.get_down_pot(), e.getPot()))
                    direction = Vector(v.x, v.y - 500)
                    self.cy.player.find_way(direction, 0.3)
                else:
                    filtered_list = [x for x in self.cy.exports if
                                     Vector.distance(x.getPot(),
                                                     self.cy.player.get_down_pot()) <= self.cy.player.wh.y * 2]

                    if len(filtered_list) >= 2:
                        v = filtered_list[0].getPot() + filtered_list[1].getPot()
                        v.scale(0.5)
                        self.cy.player.find_way(v, 0.3)
                        logo.Mlog.logger.debug(f"进入 狮子头前一个房间 中点坐标 {v}")
                    else:
                        logo.Mlog.logger.debug(f"进入 狮子头前一个房间 门柱坐标 {p.getPot()}")
                        self.cy.player.find_way(p.getPot(), 0.3)
                    # logo.Mlog.logger.error(
                    #     f"进入 狮子头前一个房间 最近的门柱{p.pot}={self.cy.player.get_down_pot().__str__()}")

    def exit(self):
        logo.Mlog.logger.debug(f"退出 狮子头前一个房间 状态")
        self.player_is_left = False
        self.player_is_up = False
        self.zst_pro_times += 0
        pass


class EntryGame:
    def __init__(self, cy: Copy):
        self.cy = cy
        self.times: int = 0

    cy: Copy = None

    def enter(self):
        # 使用 'w' 模式创建文件并写入内容
        file = open('example.txt', 'w', encoding='utf-8')
        file.write('被踢出了游戏\n')

        self.cy.is_at_town = True
        logo.Mlog.logger.error(f"进入 EntryGame 状态")

        while True:
            time.sleep(60*2)
            ast = taskPro.getAction("entryGame")
            if ast.click(3, 5):
                if self.times > 3:
                    # file = open('example.txt', 'w', encoding='utf-8')
                    file.write('注销了\n')
                    if self.cy.user.IsWeChat:
                        ast = taskPro.getAction("entryGame2w")
                        file.write('entryGame2w\n')
                    else:
                        ast = taskPro.getAction("entryGame2q")
                        file.write('entryGame2wq\n')
                    if ast.click(3, 5):
                        self.times = 0
                        time.sleep(8)
                        continue
                self.times += 1
                file.write('没有注销\n')
                # logo.Mlog.logger.debug(f"运行 赛利亚房间 状态")
                cut_role = chooseCharacter3(self.cy.role.index)
                if cut_role:
                    logo.Mlog.logger.debug(f"换角色成功{self.cy.role.job}")
                    file.write('换角色成功\n')
                    time.sleep(10)

                    ast = taskPro.getAction("goToBuWanJia")
                    if ast.click():
                        # 返回城镇成功，进入切换角色状态
                        plz = get_plz()
                        time.sleep(0.5)
                        if plz == 0:
                            action = taskPro.getAction("backTown2")
                            if action.click():
                                file.write('进入 布万家 失败 没有疲劳值了 {plz},切换角色\n')
                                logo.Mlog.logger.debug(f"进入 布万家 失败 没有疲劳值了 {plz},切换角色")
                                self.cy.sm.transition_to("house")
                                return
                            # continue
                        else:
                            ast = taskPro.getAction("fightBegen")
                            if ast.click():
                                self.cy.sm.transition_to("et")
                                self.cy.is_at_town = False
                                file.write('进入 布万家 成功\n')
                                file.close()
                                logo.Mlog.logger.debug(f"进入 布万家 成功")
                                return

    def run(self):
        # logo.Mlog.logger.debug(f"运行 空 状态")
        # self.cy.player.random_move()
        pass

    def exit(self):
        # self.file.close()  # 记得关闭文件
        logo.Mlog.logger.debug(f"退出 EntryGame 状态")


class Empty:
    def __init__(self, cy: Copy):
        self.cy = cy
        self.times = 0

    cy: Copy = None

    def enter(self):
        logo.Mlog.logger.error(f"进入 空 状态")
        self.cy.cut_room_reset()
        self.times = 0

    def run(self):
        self.times += 1
        if self.times > 20:
            self.cy.player.random_move()
            self.times = 0
        # logo.Mlog.logger.debug(f"运行 空 状态")
        # self.cy.player.random_move()
        pass

    def exit(self):
        logo.Mlog.logger.debug(f"退出 空 状态")
